package com.poi.util;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.expression.EvaluationException;
import org.springframework.expression.Expression;
import org.springframework.expression.ParseException;
import org.springframework.expression.common.TemplateParserContext;

import com.google.common.collect.Lists;
import com.poi.common.CoreConstants;
import com.poi.exp.context.PoiExporterContext;
import com.poi.log.Log;

/**
 * 正则表达式帮助类，获取对象内属性
 * 
 * @author tarena
 *
 */
public class RegexUtils {

	private static final Logger logger = LoggerFactory.getLogger(RegexUtils.class);

	/**
	 * 获取对象内属性
	 * 
	 * @param cellContent
	 * @param rootObjectItem
	 * @return
	 */
	public static List<Object> parseValueList(String cellContent, Object rootObjectItem) {
		// 处理EL表达式
		Expression expression = PoiContextUtil.getContext().getSpelExpParser().parseExpression(cellContent, new TemplateParserContext());
		List<Object> dataList = null;
		try {
			dataList = expression.getValue(PoiExporterContext.EVAL_CONTEXT, rootObjectItem, List.class);
		} catch (EvaluationException e) {
			logger.error(Log.op("ForeachRowProcessor#parseValue").msg("EL解析出错啦").toString(), e);
			dataList = new ArrayList<>(); // 异常后，原样返回，不再处理
		}
		// 处理${key}
		return dataList;
	}

	/**
	 * 获取对象内属性
	 * 
	 * @param cellContent
	 * @param rootObjectItem
	 * @return
	 */
	public static String parseValue(String cellContent, Object rootObjectItem) {
		// 处理EL表达式
		Expression expression = PoiContextUtil.getContext().getSpelExpParser().parseExpression(cellContent, new TemplateParserContext());
		String parsedContent = null;
		try {
			parsedContent = expression.getValue(PoiExporterContext.EVAL_CONTEXT, rootObjectItem, String.class);
		} catch (EvaluationException e) {
			logger.error(Log.op("ForeachRowProcessor#parseValue").msg("EL解析出错啦").toString(), e);
			return cellContent; // 异常后，原样返回，不再处理
		}
		// 处理${key}
		return resolve(parsedContent);
	}

	/**
	 * 将带有${key}和${vo.key}的内容进行替换
	 * 
	 * @param cellContent
	 * @param rootObjectMap
	 * @param parser
	 * @return
	 */
	public static String resolve(String cellContent) {
		PoiExporterContext peContext = PoiContextUtil.getContext();
		String resolvedContent = cellContent;
		if (StringUtils.isBlank(cellContent)) {
			return "";
		}
		Pattern pattern = Pattern.compile(CoreConstants.POI_MAP_ATTRIBUTE_REGEXP);
		// 处理${key}
		// logger.debug("resolvedContent={}", resolvedContent);
		for (Matcher matcher = pattern.matcher(resolvedContent); matcher.find(); matcher = pattern.matcher(resolvedContent)) {
			String key = matcher.group(1);
			String value = String.valueOf(PoiContextUtil.getContext().getRootObjectMap().get(key));
			if (value == null) {
				return "";
				// throw PoiElErrorCode.NOT_FOUND_IN_ROOTOBJECT.exp(key);
			}
			resolvedContent = matcher.replaceFirst(value);
			// fix resolvedContent 为null，直接返回
			if (resolvedContent == null) {
				return "";
			}
		}

		// 处理${vo.key}
		pattern = Pattern.compile(CoreConstants.POI_MAP_CASCADE_ATTRIBUTE_REGEXP);
		try {
			for (Matcher matcher = pattern.matcher(resolvedContent); matcher.find(); matcher = pattern.matcher(resolvedContent)) {
				String vo = matcher.group(2);
				vo = vo.substring(0, vo.length() - 1);
				Object rootObjectItem = peContext.getRootObjectMap().get(vo);
				String expression = matcher.replaceFirst("#$1$3"); // 转换成EL
				String resolvedKey = peContext.getSpelExpParser().parseExpression(expression, new TemplateParserContext()).getValue(PoiExporterContext.EVAL_CONTEXT, rootObjectItem, String.class);
				resolvedContent = resolvedKey; // 替换内容
				// fix resolvedContent 为null，直接返回
				if (resolvedContent == null) {
					return "";
				}
			}
		} catch (EvaluationException | ParseException e) {
			logger.error(Log.op("DefaultRowProcessor#resolve").msg("EL解析出错").toString(), e);
		}
		return resolvedContent;
		//return parseValue(resolvedContent,peContext.getRootObjectMap());
	}

	/**
	 * 将带有${key}和${vo.key}的内容进行替换
	 * 
	 * @param cellContent
	 * @param rootObjectMap
	 * @param parser
	 * @return
	 */
	public static List<Object> resolveList(String cellContent) {
		PoiExporterContext peContext = PoiContextUtil.getContext();
		String resolvedContent = cellContent;
		if (StringUtils.isBlank(cellContent)) {
			return Lists.newArrayList();
		}
		Pattern pattern = Pattern.compile(CoreConstants.POI_MAP_ATTRIBUTE_REGEXP);
		// 处理${key}
		// logger.debug("resolvedContent={}", resolvedContent);
		for (Matcher matcher = pattern.matcher(resolvedContent); matcher.find(); matcher = pattern.matcher(resolvedContent)) {
			String key = matcher.group(1);
			List<Object> dataList = (List) peContext.getRootObjectMap().get(key);
			if (null == dataList) {
				return Lists.newArrayList();
				// throw PoiElErrorCode.NOT_FOUND_IN_ROOTOBJECT.exp(key);
			}
			return dataList;
		}

		return Lists.newArrayList();
	}
}
